package com.huaxia.day15;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

public class ForkJoinPoolTest {
    public static void main(String[] args) {
        int count = 40000;
        List<Integer> sumList = new ArrayList<Integer>(count);
        Random random = new Random();
        for (int i = 0; i < count; i++) {
            sumList.add(random.nextInt(1000));
        }
        SumTask task = new SumTask(sumList);
        ForkJoinPool pool = new ForkJoinPool();
        int total = pool.invoke(task);
        System.out.println("total is " + total);
    }


    static class SumTask extends RecursiveTask<Integer> {
        private List<Integer> sumList;
        private int batchCount = 100;

        SumTask(List<Integer> sumList) {
            this.sumList = sumList;
        }

        @Override
        protected Integer compute() {
            int size = sumList.size();
            if (size <= batchCount) {
                return sum(sumList);
            } else {
                System.out.println("task fork ");
                int mid = size / 2;
                List<Integer> taskList1 = sumList.subList(0, mid);
                List<Integer> taskList2 = sumList.subList(mid, size);
                SumTask t1 = new SumTask(taskList1);
                SumTask t2 = new SumTask(taskList2);
//                t1.fork();
//                t2.fork();
                invokeAll(t1, t2);
                /**
                 * invokeAll 同t1.fork() t2.fork()有一定区别
                 * 调用子任务的fork方法相当于A先分工给B，然后A当监工不干活，B去完成A交代的任务。
                 * 使用invokeAll相当于A分工给B后，A和B都去完成工作。这样可以更好的利用线程池，缩短执行的时间。
                 */
                return t1.join() + t2.join();
            }
        }

        private Integer sum(List<Integer> list) {
            int total = 0;
            for (Integer value : list) {
                total += value;
            }
            return total;
        }
    }
}
